#include "LynxAudioReaderSine_C.hpp"

namespace Lynx
{
namespace Audio
{

AudioReaderMonoSine_C::AudioReaderMonoSine_C() :
    mSize(44100 * 1),
    mSamples(NULL)
{
    mSamples = new uint16_t[mSize];

    for(uint32_t a = 0; a < mSize; a++)
    {
        float x = fmod(((float)(a % 44100) / 44100.0f) * 400.0f, 1.0f) * 2.0f * Myth::Math::PI;
        mSamples[a] = (int16_t)(sin(x) * 32767.0f / 2);
    }
}

AudioReaderMonoSine_C::~AudioReaderMonoSine_C()
{
    delete mSamples;
}

AudioFormat AudioReaderMonoSine_C::get_audio_format(void) const
{
    return {1, 44100};
}

bool AudioReaderMonoSine_C::set_position(uint32_t pos)
{
    return false;
}

bool AudioReaderMonoSine_C::is_random_access(void) const
{
    return false;
}

uint32_t AudioReaderMonoSine_C::read_samples(void *buffer, uint32_t count)
{
    if(count > mSize)
        count = mSize;

    memcpy(buffer, mSamples, count * 2);

    return count;
}

uint32_t AudioReaderMonoSine_C::get_sample_count(void) const
{
    return mSize;
}

AudioReaderLoaderMonoSine_C::AudioReaderLoaderMonoSine_C()
{
    mReader = new AudioReaderMonoSine_C();
}

AudioReaderLoaderMonoSine_C::~AudioReaderLoaderMonoSine_C()
{
    mReader->decrement_counter();
}

bool AudioReaderLoaderMonoSine_C::is_loadable_extension(const std::string &file_name) const
{
    return false;
}

AudioReader *AudioReaderLoaderMonoSine_C::create_audio_reader(Myth::Stream::Input *input)
{
    return mReader;
}



AudioReaderStereoSine_C::AudioReaderStereoSine_C() :
    mSize(44100 * 10),
    mSamples(NULL)
{
    mSamples = new uint16_t[mSize];

    for(uint32_t a = 0; a < mSize; a += 2)
    {
        float x = fmod(((float)(a % 44100) / 44100.0f) * 400.0f, 1.0f) * 2.0f * Myth::Math::PI;
        mSamples[a] = (int16_t)((sin(x) * sin(x) + 1.0f) / 2.0f * 32767.0f);
        mSamples[a + 1] = (int16_t)((cos(x) * cos(x) + 1.0f) / 2.0f * 32767.0f);
    }
}

AudioReaderStereoSine_C::~AudioReaderStereoSine_C()
{
    delete mSamples;
}

AudioFormat AudioReaderStereoSine_C::get_audio_format(void) const
{
    return {2, 44100};
}

bool AudioReaderStereoSine_C::set_position(uint32_t pos)
{
    return false;
}

bool AudioReaderStereoSine_C::is_random_access(void) const
{
    return false;
}

uint32_t AudioReaderStereoSine_C::read_samples(void *buffer, uint32_t count)
{
    if(count > mSize)
        count = mSize;

    memcpy(buffer, mSamples, count * 2);

    return count;
}

uint32_t AudioReaderStereoSine_C::get_sample_count(void) const
{
    return mSize;
}

AudioReaderLoaderStereoSine_C::AudioReaderLoaderStereoSine_C()
{
    mReader = new AudioReaderMonoSine_C();
}

AudioReaderLoaderStereoSine_C::~AudioReaderLoaderStereoSine_C()
{
    mReader->decrement_counter();
}

bool AudioReaderLoaderStereoSine_C::is_loadable_extension(const std::string &file_name) const
{
    return false;
}

AudioReader *AudioReaderLoaderStereoSine_C::create_audio_reader(Myth::Stream::Input *input)
{
    return mReader;
}

} // namespace Audio
} // namespace Lynx

